﻿using System;
using System.Diagnostics.Contracts;
using FlitBit.Represent;

namespace FlitBit.Cache
{
	/// <summary>
	///   Abstract base class for caches backed by remote services.
	/// </summary>
	/// <typeparam name="TKey">key type K</typeparam>
	/// <typeparam name="TValue">value type V</typeparam>
	/// <typeparam name="TRepresentation">representation type R</typeparam>
	public abstract class RemoteRepresentationCache<TKey, TValue, TRepresentation> : RemoteCache<TKey, TValue, TRepresentation>
	{
		readonly IRepresentation<TValue, TRepresentation> _represent;

		/// <summary>
		///   Creates a new instance.
		/// </summary>
		/// <param name="name">the cache's name.</param>
		/// <param name="represent">a representation used to transform items between type V to type R.</param>
		protected RemoteRepresentationCache(string name, IRepresentation<TValue, TRepresentation> represent)
			: base(name)
		{
			Contract.Requires<ArgumentNullException>(name != null);
			Contract.Requires<ArgumentNullException>(name.Length > 0);
			Contract.Requires<ArgumentNullException>(represent != null);

			_represent = represent;
		}

		/// <summary>
		///   Restores an item from a representation
		/// </summary>
		/// <param name="representation">the representation</param>
		/// <returns>the restored item</returns>
		protected override TValue RestoreItem(TRepresentation representation)
		{
			return _represent.RestoreItem(representation);
		}

		/// <summary>
		///   Produces representation type R from an item.
		/// </summary>
		/// <param name="item">the item</param>
		/// <returns>a representation of the item</returns>
		protected override TRepresentation TransformItem(TValue item)
		{
			return _represent.TransformItem(item);
		}
	}
}